<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        #oCanvas {
            border: 1px solid #000;
        }
    
    </style>
</head>

<body>
    <canvas id="oCanvas" width="500" height="400"></canvas>
    <script type="notjs" id="vertex">
         /*
          顶点着色器 
         */
        attribute vec4 a_position;
        uniform mat4 u_matrix;
        uniform mat4 u_canvas;
        void main() {
            gl_Position =  u_canvas * u_matrix *  a_position;
        }
    </script>
    <script type="notjs" id="fragment">
        /*
            片元着色器 ： 绘制颜色或者纹理的 —— 水彩的作用
        */
        precision mediump float;

        void main() {
            gl_FragColor = vec4(0, 0, 0, 1);
        }

    </script>
    <script>
        var canvas = document.getElementById('oCanvas');
        var gl = canvas.getContext('webgl');
        if (!gl) {
            console.log('浏览器不兼容webgl');
        }

        var vertex = document.getElementById('vertex').innerText;
        var fragment = document.getElementById('fragment').innerText;

        // 顶点着色器 gl.VERTEX_SHADER   片元着色器 gl.FRAGMENT_SHADER;
        function createShader(gl, type, source) {
            var shader = gl.createShader(type);
            //  添加数据源
            gl.shaderSource(shader, source);
            gl.compileShader(shader);

            var success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
            if (success) {
                return shader;
            }
            console.log(gl.getShaderInfoLog(shader));
        }

        var vertexShader = createShader(gl, gl.VERTEX_SHADER, vertex);
        var fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragment);

        function createProgram(gl, vertexShader, fragmentShader) {
            var program = gl.createProgram();
            gl.attachShader(program, vertexShader);
            gl.attachShader(program, fragmentShader);
            gl.linkProgram(program);
            var success = gl.getProgramParameter(program, gl.LINK_STATUS);
            if (success) {
                return program;
            }
            console.log(gl.getProgramInfoLog(program));
        }
        var program = createProgram(gl, vertexShader, fragmentShader);
        gl.useProgram(program);

        gl.clearColor(0, 0, 0, 0.5);
        gl.clear(gl.COLOR_BUFFER_BIT);
        // 获取a_position 存储位置
        var a_position = gl.getAttribLocation(program, 'a_position');
        var u_matrix = gl.getUniformLocation(program, 'u_matrix');
        var u_canvas = gl.getUniformLocation(program, 'u_canvas');
        var rotateDeg = 0;

        var matrixChange = {
            position: function (width, height) {
                return [
                    2 / width, 0, 0, 0,
                    0, -2 / height, 0, 0,
                    0, 0, 1, 0,
                    -1, 1, 0, 1,
                ]
            },
            translate: function (tx, ty, tz) {
                return [1, 0, 0, 0,
                    0, 1, 0, 0,
                    0, 0, 1, 0,
                    tx, ty, tz, 1];
            },
            rotate: function (rotateDeg) {
                var sinb = Math.sin(rotateDeg * Math.PI / 180).toFixed(2);
                var cosb = Math.cos(rotateDeg * Math.PI / 180).toFixed(2);
                return [
                    cosb, sinb, 0, 0,
                    -sinb, cosb, 0, 0,
                    0, 0, 1, 0,
                    0, 0, 0, 1
                ];
            },
            scale: function (Sx, Sy, Sz) {
                return [
                    Sx, 0, 0, 0,
                    0, Sy, 0, 0,
                    0, 0, Sz, 0,
                    0, 0, 0, 1
                ]
            },



            matrixMultiply: function (a, b) {
                var a00 = a[0 * 4 + 0];
                var a01 = a[0 * 4 + 1];
                var a02 = a[0 * 4 + 2];
                var a03 = a[0 * 4 + 3];
                var a10 = a[1 * 4 + 0];
                var a11 = a[1 * 4 + 1];
                var a12 = a[1 * 4 + 2];
                var a13 = a[1 * 4 + 3];
                var a20 = a[2 * 4 + 0];
                var a21 = a[2 * 4 + 1];
                var a22 = a[2 * 4 + 2];
                var a23 = a[2 * 4 + 3];
                var a30 = a[3 * 4 + 0];
                var a31 = a[3 * 4 + 1];
                var a32 = a[3 * 4 + 2];
                var a33 = a[3 * 4 + 3];
                var b00 = b[0 * 4 + 0];
                var b01 = b[0 * 4 + 1];
                var b02 = b[0 * 4 + 2];
                var b03 = b[0 * 4 + 3];
                var b10 = b[1 * 4 + 0];
                var b11 = b[1 * 4 + 1];
                var b12 = b[1 * 4 + 2];
                var b13 = b[1 * 4 + 3];
                var b20 = b[2 * 4 + 0];
                var b21 = b[2 * 4 + 1];
                var b22 = b[2 * 4 + 2];
                var b23 = b[2 * 4 + 3];
                var b30 = b[3 * 4 + 0];
                var b31 = b[3 * 4 + 1];
                var b32 = b[3 * 4 + 2];
                var b33 = b[3 * 4 + 3];
                return [
                    a00 * b00 + a01 * b10 + a02 * b21 + a03 * b30,
                    a00 * b01 + a01 * b11 + a02 * b21 + a03 * b31,
                    a00 * b02 + a01 * b12 + a02 * b22 + a03 * b32,
                    a00 * b03 + a01 * b13 + a02 * b23 + a03 * b33,

                    a10 * b00 + a11 * b10 + a12 * b21 + a13 * b30,
                    a10 * b01 + a11 * b11 + a12 * b21 + a13 * b31,
                    a10 * b02 + a11 * b12 + a12 * b22 + a13 * b32,
                    a10 * b03 + a11 * b13 + a12 * b23 + a13 * b33,

                    a20 * b00 + a21 * b10 + a22 * b21 + a23 * b30,
                    a20 * b01 + a21 * b11 + a22 * b21 + a23 * b31,
                    a20 * b02 + a21 * b12 + a22 * b22 + a23 * b32,
                    a20 * b03 + a21 * b13 + a22 * b23 + a23 * b33,
                    
                    a30 * b00 + a31 * b10 + a32 * b21 + a33 * b30,
                    a30 * b01 + a31 * b11 + a32 * b21 + a33 * b31,
                    a30 * b02 + a31 * b12 + a32 * b22 + a33 * b32,
                    a30 * b03 + a31 * b13 + a32 * b23 + a33 * b33
                ];

            }
        }
        
        var deg = 0;
        function rotate() {
            deg += 1;
            draw(deg);
            requestAnimationFrame(rotate)
        }
        draw(deg);
        function draw(deg) {
            var Tx = 100.0, Ty = 0, Tz = 0;
            var Sx = 1, Sy = 0.5, Sz = 0;
            var rotateMatrix = matrixChange.rotate(deg);
            var translateMatrix = matrixChange.translate(Tx, Ty, Tz);
            var scaleMatrix = matrixChange.scale(Sx, Sy, Sz);
            var matrix = matrixChange.matrixMultiply(rotateMatrix, translateMatrix);
            matrix = matrixChange.matrixMultiply(scaleMatrix, matrix)
            gl.uniformMatrix4fv(u_canvas, false, new Float32Array(matrixChange.position(canvas.width, canvas.height)));
            gl.uniformMatrix4fv(u_matrix, false, new Float32Array(matrix));
            var positionBuffer = gl.createBuffer();
            gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
            gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
                50.0, 50.0, 0.0,
                100, 100, 0.0,
                50.0, 100, 0.0,
                50.0, 50.0, 0.0,
                100, 50.0, 0.0,
                100, 100, 0.0,
            ]), gl.STATIC_DRAW);

            gl.vertexAttribPointer(a_position, 3, gl.FLOAT, true, 0, 0);
            gl.enableVertexAttribArray(a_position);
            gl.drawArrays(gl.TRIANGLES, 0, 6);
        }


    </script>
</body>

</html>
